﻿using Cdy.Tag;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MarsUniformApiExample
{
    /// <summary>
    /// DriverApiTest.xaml 的交互逻辑
    /// </summary>
    public partial class DriverApiTest : UserControl
    {
        Dictionary<string, int> mTagids = new Dictionary<string, int>();

        Dictionary<int, int> mTagTypes = new Dictionary<int, int>();

        Dictionary<int, string> mTagNames = new Dictionary<int, string>();

        //private DirectAccessDriver.ClientApi.DirectAccessClient mProxy;
        private MarsUniformApi.MarsApi mProxy;

        public MarsUniformApi.MarsApi Proxy
        {
            get { return mProxy; }
            set { mProxy = value; Init(); }
        }

        public DriverApiTest()
        {
            InitializeComponent();
            htimestart.Text = DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd HH:mm:ss");
            htimeend.Text = DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd HH:mm:ss");
            //tc.IsEnabled = false;
        }

        private void Login_Click(object sender, RoutedEventArgs e)
        {
            //mProxy = new DirectAccessDriver.ClientApi.DirectAccessClient();
            //string[] svstr = this.server.Text.Split(new char[] { ':' });
            //mProxy.Open(svstr[0], int.Parse(svstr[1]));
            //mProxy.Login(user.Text, pass.Text);

            //tc.IsEnabled = mProxy.IsLogin;
            //if (mProxy.IsLogin)
            //{
            //    MessageBox.Show("登录成功!");
            //}
            //else
            //{
            //    MessageBox.Show("登录失败!");
            //}

            
        }

        private void Init()
        {
            if (mProxy == null) return;

            //订购变量值改变通知
            mProxy.SetValueChangeCallBackForCollector(new DirectAccessDriver.ClientApi.DirectAccessClient.ProcessDataPushDelegate((vals) => {
                StringBuilder sb = new StringBuilder();
                if (vals != null)
                {
                    foreach (var vv in vals)
                    {
                        sb.AppendLine($"变量:{vv.Key} 值:{vv.Value}");
                    }
                }
                this.Dispatcher.Invoke(() => {
                    this.valchangemsg.AppendText(sb.ToString());
                });
            }));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryAllTag_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var vtags = mProxy.QueryAllTagIdAndNamesForCollector();
                mTagids.Clear();
                mTagTypes.Clear();
                mTagNames.Clear();

                if (vtags != null)
                {
                    foreach (var vv in vtags)
                    {
                        mTagids.Add(vv.Value.Item1, vv.Key);
                        mTagNames.Add(vv.Key, vv.Value.Item1);
                        mTagTypes.Add(vv.Key, vv.Value.Item2);
                    }
                }

                var rds = mProxy.GetDriverRecordTypeTagIdsForCollector();

                itmsg.Text = $"变量个数:{ mTagids.Count } 变量ID  Min:{mTagids.Values.Min() }   Max:{mTagids.Values.Max()}  驱动记录类型的变量个数:{rds.Count}";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 写入一段历史数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void hsetval_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int sname = mTagids[htagname.Text];
                DateTime stime = DateTime.Parse(htimestart.Text).ToUniversalTime();
                DateTime etime = DateTime.Parse(htimeend.Text).ToUniversalTime();
                int spen = int.Parse(htimspan.Text);
                Dictionary<DateTime, double> values = new Dictionary<DateTime, double>();
                Random rd = new Random((int)DateTime.Now.Ticks);
                DateTime dt = stime;
                double i=DateTime.Now.Second;
                while (dt <= etime)
                {
                    values.Add(dt, i++);
                    dt = dt.AddSeconds(spen);
                }

                DirectAccessDriver.ClientApi.HisDataBuffer hbuffer = new DirectAccessDriver.ClientApi.HisDataBuffer();
                foreach (var vv in values)
                {
                    hbuffer.AppendValue(vv.Key, vv.Value, 0);
                }

                mProxy.SetTagHisValueForCollector(sname, (Cdy.Tag.TagType)mTagTypes[sname], hbuffer);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        /// <summary>
        /// 写入实时数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void settagvalueb_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (tagmodsel.IsChecked.Value)
                {
                    int id = mTagids[rtname.Text];
                    double dval = double.Parse(rtval.Text);
                    mProxy.SetTagValueAndQualityForCollector(new List<RealTagValue>() { new RealTagValue() { Id = id, Value = dval, ValueType = 8, Quality = 0 } });
                }
                else
                {
                    DirectAccessDriver.ClientApi.RealDataBuffer rbuffer = new DirectAccessDriver.ClientApi.RealDataBuffer();
                    double dval = double.Parse(rtval.Text);
                    for (int i = int.Parse(rtsid.Text); i <= int.Parse(rteid.Text); i++)
                    {
                        rbuffer.AppendValue(i, dval, 0);
                    }
                    mProxy.SetTagValueAndQualityForCollector(rbuffer);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void settagvalb2_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int id = mTagids[rtname.Text];
                Task.Run(() => {

                    //double dval = double.Parse(rtval.Text);
                    while (true)
                    {
                        mProxy.SetTagRealAndHisValueWithTimerForCollector(new List<RealTagValueWithTimer>() { new RealTagValueWithTimer() { Id = id, Value = DateTime.UtcNow.Second, ValueType = 8, Quality = 0, Time = DateTime.UtcNow } });
                        Thread.Sleep(2000);
                    }
                });
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 订购值改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void regb_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var vatgs = rntagname.Text.Split(new char[] { ',' }).Select(ee => mTagids[ee]);
                mProxy.AppendRegistorDataChangedCallBackForCollector(vatgs);
                MessageBox.Show("订购完成!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void rdg_Click(object sender, RoutedEventArgs e)
        {
            rtval.Text = new Random((int)DateTime.Now.Ticks).NextDouble().ToString();
        }

        private void settagvaluebonedirection_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (tagmodsel.IsChecked.Value)
                {
                    int id = mTagids[rtname.Text];
                    double dval = double.Parse(rtval.Text);
                    mProxy.SetTagValueAndQuality2ForCollector(new List<RealTagValue2>() { new RealTagValue2() { Id = rtname.Text, Value = dval, ValueType = 8, Quality = 0 } });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 一次写入多个变量的一段的历史值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void hsetval2_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int sid = int.Parse(htagnames.Text);
                int eid = int.Parse(htagnamee.Text);

                DateTime stime = DateTime.Parse(htimestart.Text);
                DateTime etime = DateTime.Parse(htimeend.Text);
                int spen = int.Parse(htimspan.Text);
                Dictionary<DateTime, double> values = new Dictionary<DateTime, double>();
                Random rd = new Random((int)DateTime.Now.Ticks);
                DateTime dt = stime;
                while (dt <= etime)
                {
                    values.Add(dt, rd.NextDouble());
                    dt = dt.AddSeconds(spen);
                }


                DirectAccessDriver.ClientApi.HisDataBuffer hbuffer = new DirectAccessDriver.ClientApi.HisDataBuffer();
                int cc = 0;
                for (int i = sid; i <= eid; i++)
                {
                    hbuffer.Write(i);
                    hbuffer.Write(values.Count);
                    hbuffer.Write((byte)TagType.Double);
                    foreach (var vv in values)
                    {
                        hbuffer.AppendValue(vv.Key, vv.Value, 0);
                    }
                    cc++;
                }

                mProxy.SetMutiTagHisValueForCollector(hbuffer, cc);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void settagvaluewithTimer_Click(object sender, RoutedEventArgs e)
        {
            string[] tags = histagnames.Text.Split(new char[] { ',' });
            double timeoffset = double.Parse(hisvaluetimeoffset.Text);
            if (tags.Length > 0)
            {
                var vids = mProxy.GetTagIdsForConsumer(tags.ToList());
                settagvaluewithTimer.IsEnabled = false;

                Task.Run(() => {
                    while (true)
                    {
                        try
                        {
                            List<RealTagValueWithTimer> vals = new List<RealTagValueWithTimer>(tags.Length);
                            DateTime dnow = DateTime.UtcNow;
                            for (int i = 0; i < tags.Length; i++)
                            {
                                vals.Add(new RealTagValueWithTimer() { Id = vids[tags[i]], Quality = 0, Time = dnow.AddMinutes(timeoffset), Value = dnow.Second, ValueType = (byte)TagType.Double });
                            }

                            mProxy.SetTagRealAndHisValueWithTimerForCollector(vals);

                            Thread.Sleep(10000);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }

                    }
                });
            }

        }

        private void settagvaluewithTimeronce_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string[] tags = histagnames.Text.Split(new char[] { ',' });
                double timeoffset = double.Parse(hisvaluetimeoffset.Text);
                if (tags.Length > 0)
                {
                    var vids = mProxy.GetTagIdsForConsumer(tags.ToList());
                 
                    List<RealTagValueWithTimer> vals = new List<RealTagValueWithTimer>(tags.Length);
                    DateTime dnow = DateTime.UtcNow;
                    for (int i = 0; i < tags.Length; i++)
                    {
                        vals.Add(new RealTagValueWithTimer() { Id = vids[tags[i]], Quality = 0, Time = dnow.AddMinutes(timeoffset), Value = dnow.Second, ValueType = (byte)TagType.Double });
                    }

                   bool re = mProxy.SetTagRealAndHisValueWithTimerForCollector(vals);
                    if(re)
                    {
                        MessageBox.Show("写入成功!");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartWrite_Click(object sender, RoutedEventArgs e)
        {
            ProcessTagHisValueSet2();
        }

        private void ProcessTagHisValueSet2()
        {
            int sid = int.Parse(fromId.Text);
            int eid = int.Parse(toId.Text);
            int circle = int.Parse(writeCircle.Text);
            List<RealTagValueWithTimer> hbuffer = new List<RealTagValueWithTimer>(eid * 32);
            Task.Run(() => {

                int valvount = 0;
                while (true)
                {
                    mProxy.CheckAndRemoveTimeoutDataForCollector();

                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    hbuffer.Clear();
                    DateTime date = DateTime.UtcNow;
                    int cc = 0;
                    double dval = Math.Sin(valvount / 180.0 * Math.PI);
                    for (int i = sid; i <= eid; i++)
                    {
                        hbuffer.Add(new RealTagValueWithTimer() { Id = i, ValueType = (byte)TagType.Double, Quality = 0, Time = date, Value = dval });
                        //hbuffer.AppendTagValueAndQuality(i, TagType.Double, dval, 0);
                        //hbuffer.AppendTagValueAndQualityWithTimer(i, TagType.Double, dval, date, 0);
                        cc++;
                    }
                    long ltmp = sw.ElapsedMilliseconds;

                    mProxy.SetTagRealAndHisValueWithTimerForCollectorAsync(hbuffer, (result) => {
                        sw.Stop();
                        if (result)
                        {
                            string slog = $"{valvount} {date} 写入值:{dval} 数据准备耗时:{ltmp}ms  写入耗时:{sw.ElapsedMilliseconds - ltmp} ms " + "\r\n";
                            this.Dispatcher.Invoke(new Action(() =>
                            {
                                if (valvount % 10 == 0)
                                {
                                    log.SelectAll();
                                    log.Selection.Text = "\r\n";
                                }
                                log.AppendText(slog);
                                log.ScrollToEnd();

                            }));
                        }
                        else
                        {
                            string slog = $"写入超时 " + "\r\n";
                            this.Dispatcher.Invoke(new Action(() =>
                            {
                                log.AppendText(slog);
                                log.ScrollToEnd();
                            }));
                        }
                    }, 5000);
                    valvount++;
                    Thread.Sleep(circle * 1000);
                }
            });
        }
    }
}
